﻿<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">

	<head>
		<meta content="text/html; charset=utf-8" http-equiv="Content-Type" />
		<title>Unit of Work</title>
		<link type="text/css" rel="stylesheet" href="bootstrap.min.css" />
	</head>

	<body>

		<div class="document-contents">

			<h3 id="DocCommonApproaches">Introduction</h3>
			<p>Connection and transaction management is one of the most important concepts 
in an application that uses a database. When to open a connection, when to 
start a transaction, how to dispose the connection and so on.. ASP.NET Boilerplate manages database connection and transactions 
			by it's <strong>unit of work</strong> system.</p>
			<h3 id="DocAbpApproach">Connection &amp; Transaction Management in ASP.NET Boilerplate</h3>
			<p>
				ASP.NET Boilerplate <strong>opens
				</strong>a database connection (it may not be opened immediately, but opened in 
first database usage, based on ORM provider implementation) and begins a <strong>transaction </strong>when
				<strong>entering </strong>a <strong>unit of work method</strong>. 
				So, you can use connection safely in this method. At the end of the method, the transaction is <strong>
commited</strong> and the connection is <strong>disposed</strong>. If the 
method throws any <strong>exception</strong>, transaction is <strong>
rolled back</strong> and the connection is disposed. In this way, a unit of work method is <strong>atomic</strong> (a <strong>unit of work</strong>). ASP.NET Boilerplate does 
all of these automatically.</p>
			<p>If a unit of work method calls another unit of work method, both uses same 
connection &amp; transaction. The first entering method manages connection &amp; 
transaction, others use it.</p>
			<h4>Conventional Unit Of Work Methods</h4>
			<p>Some methods are unit of work methods by default:</p>
			<ul>
				<li>All <a href="MVC-Controllers.html">MVC</a>,
				<a href="Web-API-Controllers.html">Web API</a> and
				<a href="AspNet-Core.html">ASP.NET Core MVC</a> Controller 
				actions.</li>
				<li>All <a href="Application-Services.html">Application Service</a> 
				methods.</li>
				<li>All <a href="Repositories.html">Repository</a> methods.</li>
			</ul>
			<p>&nbsp;Assume that we have an <a href="/Pages/Documents/Application-Services">
application service</a> method like below:</p>
			<pre lang="cs">public class PersonAppService : IPersonAppService
{
    private readonly IPersonRepository _personRepository;
    private readonly IStatisticsRepository _statisticsRepository;

    public PersonAppService(IPersonRepository personRepository, IStatisticsRepository statisticsRepository)
    {
        _personRepository = personRepository;
        _statisticsRepository = statisticsRepository;
    }

    public void CreatePerson(CreatePersonInput input)
    {
        var person = new Person { Name = input.Name, EmailAddress = input.EmailAddress };
        _personRepository.Insert(person);
        _statisticsRepository.IncrementPeopleCount();
    }
}</pre>

			<p>In the CreatePerson method, we're inserting a person using person repository 
and incrementing total people count using statistics repository. Both of 
repositories <strong>shares </strong>same connection and transaction in this 
example since application service method is unit of work by default. ASP.NET Boilerplate opens a 
database connection and starts a transaction when entering CreatePerson method 
and commit the transaction at end of the method if no exception is thrown, 
rolls back if any exception occurs. In that way, all database operations in 
CreatePerson method becomes <strong>atomic</strong> (<strong>unit of work</strong>).&nbsp;</p>
			<p>In addition to default conventional unit of work classes, you can 
			add your own convention in PreInitialize method of your
			<a href="Module-System.html">module</a> like below:</p>
			<pre lang="cs">Configuration.UnitOfWork.ConventionalUowSelectors.Add(type =&gt; ...);</pre>
			<p>You should check type and return true if this type should be a 
			conventional unit of work class.</p>
			<h4 id="DocUow">Controlling Unit Of Work</h4>
			<p>Unit of work <strong>implicitly</strong> works for the methods 
			defined above. 
			In most cases you don't have to control unit of work manually for 
			web applications. You can <strong>explicitly </strong>use it if you want to control unit of 
			work somewhere else. There are two approaches for it.&nbsp;</p>
			<h5>UnitOfWork Attribute</h5>
			<p>First and preferred approach is using <strong>UnitOfWork</strong> 
			attribute. Example:</p>
			<pre lang="cs"><strong>[UnitOfWork]</strong>
public void CreatePerson(CreatePersonInput input)
{
    var person = new Person { Name = input.Name, EmailAddress = input.EmailAddress };
    _personRepository.Insert(person);
    _statisticsRepository.IncrementPeopleCount();
}</pre>
			<p>Thus, CreatePerson methods becomes unit of work and manages database 
connection and transaction, both repositories use same unit of work. Note that 
no need to UnitOfWork attribute if this is an application service method. Also see '<a href="#DocUowRestrictions">unit 
of work method restrictions</a>' section.</p>
			<p>There are some options of the UnitOfWork attribute. See 'unit of work in 
detail' section. UnitOfWork attribute can also be used for classes to configure 
			all methods of a class. Method attribute overrides the class 
			attribute if exists.</p>
			<h5>IUnitOfWorkManager</h5>
			<p>Second appropaches is using the <strong>IUnitOfWorkManager.Begin(...)</strong> 
method as 
shown below:</p>
			<pre lang="cs">public class MyService
{
    private readonly IUnitOfWorkManager _unitOfWorkManager;
    private readonly IPersonRepository _personRepository;
    private readonly IStatisticsRepository _statisticsRepository;

    public MyService(IUnitOfWorkManager unitOfWorkManager, IPersonRepository personRepository, IStatisticsRepository statisticsRepository)
    {
        _unitOfWorkManager = unitOfWorkManager;
        _personRepository = personRepository;
        _statisticsRepository = statisticsRepository;
    }

    public void CreatePerson(CreatePersonInput input)
    {
        var person = new Person { Name = input.Name, EmailAddress = input.EmailAddress };

        using (var unitOfWork = _unitOfWorkManager.Begin())
        {
            _personRepository.Insert(person);
            _statisticsRepository.IncrementPeopleCount();

            unitOfWork.Complete();
        }
    }
}</pre>
			<p>You can inject and use IUnitOfWorkManager as shown here (Some 
			base classes have already <strong>UnitOfWorkManager</strong> 
			injected by default: MVC Controllers,
			<a href="Application-Services.html">application services</a>,
			<a href="Domain-Services.html">domain services</a>...). Thus, you can create more <strong>limited scope</strong> unit of works. In this approach, you 
should call <strong>Complete</strong> method manually. If you don't call, 
transaction is rolled back and changes are not saved.</p>
			<p>Begin method has overloads 
to set <strong>unit of work options</strong>. It's better and 
shorter to use <strong>UnitOfWork</strong> attribute if you don't have a good reason.</p>

			<h3 id="DocUowDetails">Unit Of Work in Detail</h3>
			<h4 id="DocDisablingUow">Disabling Unit Of Work</h4>
			<p>You may want to disable unit of work <strong>for conventional 
			unit of work methods</strong> . To do 
that, use UnitOfWorkAttribute's <strong>IsDisabled</strong> property. Example usage:</p>
			<pre lang="cs"><strong>[UnitOfWork(IsDisabled = true)]</strong>
public virtual void RemoveFriendship(RemoveFriendshipInput input)
{
    _friendshipRepository.Delete(input.Id);
}
			</pre>
			<p>Normally, you don't want to do that, but in some situations you 
			may want to disable unit of work:</p>
			<ul>
				<li>You may want to use unit of work in a limited scope with UnitOfWorkScope 
	class described above.</li>
			</ul>
			<p>Note that if a unit of work method calls this RemoveFriendship method, 
disabling this method is ignored and it uses the same unit of work with the caller method. 
So, use disabling by carefully. Also, the code above works well since repository 
methods are unit of work by default.</p>
			<h4 id="DocUowNoTransaction">Non-Transactional Unit Of Work</h4>
			<p>A unit of work is transactional as default (by it's nature). Thus, ASP.NET 
Boilerplate starts/commits/rollbacks an explicit database-level transaction. In 
some special cases, transaction may cause problems since it may lock some rows 
or tables in the database. In this situations, you may want to disable 
database-level transaction. UnitOfWork attribute can get a boolean value in it's 
constructor to work as non-transactional. Example usage:</p>
			<pre lang="cs"><strong>[UnitOfWork(</strong><span lang="tr"><strong>isTransactional: </strong></span><strong>false)]</strong>
public GetTasksOutput GetTasks(GetTasksInput input)
{
    var tasks = _taskRepository.GetAllWithPeople(input.AssignedPersonId, input.State);
    return new GetTasksOutput
            {
                Tasks = Mapper.Map&lt;List&lt;TaskDto&gt;&gt;(tasks)
            };
}</pre>
			<p>I suggest to use this attribute as <strong>[UnitOfWork(isTransactional: false)]</strong>. 
I think it's more readable and explicit. But you can use as [UnitOfWork(false)].</p>
			<p>Note that ORM frameworks (like NHibernate and EntityFramework) internally 
saves changes in a single command. Assume that you updated a few Entities in a 
non-transactional UOW. Even in this situation all updates are performed at end 
of the unit of work with a single database command. But if you execute an SQL 
query directly, it's performed immediately and not rolled back if your UOW is 
			not transactional.</p>
			<p>There is a restriction for non-transactional UOWs. If you're already in a 
transactional unit of work scope, setting isTransactional to false is ignored 
			(use Transaction Scope Option to create a non-transactional unit of 
			work in a transactional unit of work).</p>
			<p>Use non-transactional unit of works carefully since most of the times it 
should be transactional for data integrity. If your method just reads data, not 
changes it, it can be safely non-transactional.</p>
			<h4 id="DocUowCallsOtherMethod">A Unit Of Work Method Calls Another</h4>
			<p>Unit of work is ambient. If a unit of work method calls another 
			unit of work method, they share same connection and transaction. 
			First method manages connection, others use it.</p>
			<h4>Unit Of Work Scope</h4>
			<p>You can create a different and isolated transaction in another transaction or 
can create a non-transactional scope in a transaction. .NET defines
				<a href="https://msdn.microsoft.com/en-us/library/system.transactions.transactionscopeoption(v=vs.110).aspx" target="_blank">
TransactionScopeOption</a> for that. You can set Scope option of the unit of 
work to control it. </p>
			<h4 id="DocAutoSaveChanges">Automatically Saving Changes</h4>
			<p>If a method is unit of work, ASP.NET Boilerplate saves 
all changes at the end of the method automatically. Assume that we need method to update name of a person:</p>
			<pre lang="cs"><strong>[UnitOfWork]</strong>
public void UpdateName(UpdateNameInput input)
{
    var person = _personRepository.Get(input.PersonId);
    <strong>person.Name = input.NewName;</strong>
}</pre>
			<p>That's all, name was changed! We did not even called _personRepository.Update 
method. O/RM framework keep track of all changes of entities in a unit of work 
and reflects changes to the database.</p>
			<p>Note that no need to declare UnitOfWork for conventional unit of 
			work methods.</p>
			<h4 id="DocRepositoryGetAll">IRepository.GetAll() Method</h4>
			<p>When you call GetAll() out of a repository method, there must be an open database connection since it 
returns IQueryable. This is needed because of deferred execution of IQueryable<T>. It does not perform database query unless you call ToList() method or use the IQueryable<T> in a foreach loop (or somehow access to queried items). So, when you call ToList() method, database connection must be alive.</p>
					<p>Consider the example below:</p>
					<pre lang="cs"><strong>[UnitOfWork]</strong>
public SearchPeopleOutput SearchPeople(SearchPeopleInput input)
{
    //Get IQueryable&lt;Person&gt;
    var query = <strong>_personRepository.GetAll();</strong>

    //Add some filters if selected
    if (!string.IsNullOrEmpty(input.SearchedName))
    {
        query = query.Where(person =&gt; person.Name.StartsWith(input.SearchedName));
    }

    if (input.IsActive.HasValue)
    {
        query = query.Where(person =&gt; person.IsActive == input.IsActive.Value);
    }

    //Get paged result list
    var people = query.Skip(input.SkipCount).Take(input.MaxResultCount).ToList();

    return new SearchPeopleOutput { People = Mapper.Map&lt;List&lt;PersonDto&gt;&gt;(people) };
}</pre>
					<p>Here, SearchPeople method must be unit of work since ToList() method of IQueryable is 
called in the method body, and database connection must be open when 
IQueryable.ToList() is executed.</p>
					<p>In most cases you will use GetAll method safely in a web 
					application, since all controller actions are unit of work 
					by default and thus database connection is available in 
					entire request.</p>
					<h4 id="DocUowRestrictions">UnitOfWork Attribute Restrictions</h4>
					<p>You can use UnitOfWork attribute for;</p>
					<ul>
						<li>All <strong>public</strong> or <strong>public virtual</strong> methods for classes 
	those are used over interface 
	(Like an application service used over service interface).</li>
						<li>All <strong>public virtual</strong> methods for self injected classes (Like
							<strong>MVC Controllers</strong> and <strong>Web API Controllers</strong>).</li>
						<li>All <strong>protected virtual</strong> methods.</li>
					</ul>
					<p>It's suggested to always make the method <strong>virtual</strong>.&nbsp;You can 
						<strong>not use it for private methods</strong>. 
Because, ASP.NET Boilerplate uses dynamic proxying for that and private methods 
can not be seen by derived classes. UnitOfWork attribute (and any proxying) does 
not work if you don't use <a href="/Pages/Documents/Dependency-Injection">
dependency injection</a> and instantiate the class yourself.</p>

					<h3 id="DocUowOptions">Options</h3>
					<p>There are some options can be used to change behaviour of a unit of work.</p>
					<p>First, we can change default values of all unit of works in the
						<a href="/Pages/Documents/Startup-Configuration">startup configuration</a>. This 
is generally done in PreInitialize method of our
						<a href="/Pages/Documents/Module-System">module</a>.</p>
					<pre lang="cs">public class SimpleTaskSystemCoreModule : AbpModule
{
    public override void PreInitialize()
    {
        Configuration.UnitOfWork.IsolationLevel = IsolationLevel.ReadCommitted;
        Configuration.UnitOfWork.Timeout = TimeSpan.FromMinutes(30);
    }

    //...other module methods
}</pre>
					<p>Second, we can override defaults for a particular unit of work. For that, <strong>
UnitOfWork </strong> attribute constructor and IUnitOfWorkManager.<strong>Begin</strong> 
method have overloads to get options.</p>
			<p>And lastly, you can use startup configuration to configure 
			default unit of work attributes for ASP.NET MVC, Web API and ASP.NET 
			Core MVC Controllers (see their documentation).</p>
					<h3 id="DocUowMethods">Methods</h3>
					<p>UnitOfWork system works seamlessly and invisibly. But, in some special cases, 
you need to call it's methods.</p>
			<p>You can access to current unit of work in one of two ways:</p>
			<ul>
				<li>You can directly use <strong>CurrentUnitOfWork</strong> 
				property if your class is derived from some specific base 
				classes (ApplicationService, DomainService, AbpController, 
				AbpApiController... etc.)</li>
				<li>You can inject IUnitOfWorkManager into any class and&nbsp;use
				<strong>IUnitOfWorkManager.Current</strong> property.</li>
			</ul>
					<h4 id="DocUowSaveChanges">SaveChanges</h4>
					<p>ASP.NET Boilerplate saves all changes at end of a unit of 
					work, you don't have to do anything. But, sometimes, you may 
					want to save changes to database in middle of a unit of work 
					operation. An example 
usage may be saving changes to get Id of a new inserted
						<a href="/Pages/Documents/Entities">Entity</a> in <a href="/Pages/Documents/EntityFramework-Integration">
EntityFramework</a>.</p>
			<p>You can use <strong>SaveChanges </strong>or <strong>
			SaveChangesAsync </strong>method of current unit of work.</p>
			<p>&nbsp;Note that: if current unit of work is transactional, all 
			changes in the transaction are rolled back if an exception occurs, 
			even saved changes.</p>

					<h3 id="DocEvents">Events</h3>
					<p>A unit of work has <strong>Completed</strong>, <strong>Failed</strong> and <strong>Disposed</strong> 
					events. You can register to these events and perform needed 
					operations. For example,yYou may want to run some code when current unit of work successfully 
completed. Example:</p>
					<pre lang="cs">public void CreateTask(CreateTaskInput input)
{
    var task = new Task { Description = input.Description };

    if (input.AssignedPersonId.HasValue)
    {
        task.AssignedPersonId = input.AssignedPersonId.Value;
        <strong>_unitOfWorkManager.Current.Completed</strong> += (sender, args) =&gt; { /* TODO: Send email to assigned person */ };
    }

    _taskRepository.Insert(task);
}</pre>

				</div>

			</body>

		</html>
		
